package com.njym.payment.alipay;

/**
 * @program: chpp
 * @description:
 * @author: Mr.LI
 * @create: 2018-08-21 13:52
 **/

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.njym.entity.PlatformBusinessRec;
import com.njym.entity.SysOrganization;
import com.njym.entity.SysPaymentMode;
import com.njym.payment.alipay.api.AlipayConfig;
import com.njym.payment.alipay.properties.*;
import com.njym.service.PlatformBusinessRecService;
import com.njym.service.SysOrganizationService;
import com.njym.tradeStatusConfig.AliTradeStatus;
import com.njym.vo.Json;
import com.njym.webservice.WebService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "支付宝支付接口", produces = MediaType.ALL_VALUE)
@RestController
@RequestMapping("/alipay_api")
public class AliPayApiController {

	private static final Logger log = LoggerFactory.getLogger(AliPayApiController.class);

	@Autowired
	private PlatformBusinessRecService platformBusinessRecService;

	@Autowired
	private WebService webService;

	@Autowired
	private SysOrganizationService sysOrganizationService;

	@Resource
	private GetAliPayClient getAliPayClient;

	/**
	 * 支付宝查询退款状态接口
	 *
	 * @param prepayParams
	 * @return
	 */
	@ApiOperation(value = "支付宝查询退款状态接口", notes = "直接返回退款状态", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "商户生成的交易号", name = "outTradeNo", required = true, dataType = "String", example = "20190222130826711"),
	})
	@PostMapping("/queryRefundStatus")
	public Json queryRefundStatus(@Valid QueryRefundParams prepayParams, BindingResult bindingResult) {
		String oper = "alipay_refund_query";
		log.info("{}, body: {}", oper, prepayParams);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String values = "";
		String tradeNo = "";
		BigDecimal bigDecimal = BigDecimal.ZERO;
		String orgId = prepayParams.getOrgId();

		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(orgId);
		if (alipayClient == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		//查询此次交易号
		String requestNo;
		List<PlatformBusinessRec> list = platformBusinessRecService.getPlatformByOutTradeNo(prepayParams.getOutTradeNo());
		if (list.size() > 0) {
			for (PlatformBusinessRec platformBusinessRec : list) {
				requestNo = platformBusinessRec.getOutRequestNo();
				AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
				request.setBizContent("{" + "\"out_trade_no\":\"" + prepayParams.getOutTradeNo() + "\"," + "\"out_request_no\":\"" + requestNo + "\"" + "  }");
				try {
					AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
					if (response.isSuccess()) {
						System.out.println("调用成功");
						String num = "0";
						if (org.apache.commons.lang.StringUtils.isNotBlank(response.getRefundAmount())) {
							num = response.getRefundAmount();
						}
						BigDecimal bigDecimal1 = new BigDecimal(num);
						bigDecimal = bigDecimal.add(bigDecimal1);
						values = "REFUND_SUCCESS";
					} else {
						values = "QUERY_FAILURE";
						System.out.println("调用失败");
					}
				}
				catch (AlipayApiException e) {
					e.printStackTrace();
					values = "QUERY_FAILURE";
				}
			}
		} else {
			return Json.succ(true, "NOT_REFUND", "", tradeNo);
		}
		if (bigDecimal.compareTo(BigDecimal.ZERO) == 0) {
			values = "REFUND_FAILURE";
		}
		return Json.succ(true, oper, values, bigDecimal.toString());
	}

	/**
	 * 查询订单支付状态
	 *
	 * @param prepayParams
	 * @return
	 */
	@ApiOperation(value = "支付宝查询交易状态接口", notes = "直接返回交易状态", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "商户生成的交易号", name = "outTradeNo", required = true, dataType = "String", example = "20190222130826711"),
	})
	@PostMapping("/queryStatus")
	public Json queryStatus(@Valid QueryRefundParams prepayParams, BindingResult bindingResult) {
		String oper = "alipay_query";
		log.info("{}, body: {}", oper, prepayParams);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String values = "";
		String tradeNo = "";
		String orgId = prepayParams.getOrgId();

		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(orgId);
		if (aliPayProperties == null || alipayClient == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		request.setBizContent("{" + "\"out_trade_no\":\"" + prepayParams.getOutTradeNo() + "\"" + "  }");

		PlatformBusinessRec businessRec = null;
		try {
			AlipayTradeQueryResponse response = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
			if (AliTradeStatus.QUERY_SUCCESS.equals(response.getCode())) {
				switch (response.getTradeStatus()) {
					case AliTradeStatus.WAIT_BUYER_PAY:
						values = "WAIT_BUYER_PAY";
						break;
					case AliTradeStatus.TRADE_SUCCESS:
						values = "TRADE_SUCCESS";
						tradeNo = response.getTradeNo();
						//查询数据库
						businessRec = platformBusinessRecService.getPlatformByOutTradeNos(prepayParams.getOutTradeNo()).get(0);
						if (businessRec != null && org.apache.commons.lang.StringUtils.isBlank(businessRec.getTradeNo())) {
							businessRec.setTradeStatus(AliTradeStatus.TRADE_SUCCESS);
							businessRec.setTradeNo(tradeNo);
							businessRec.setTradeDate(new Date());
							platformBusinessRecService.updateById(businessRec);
						}
						break;
					case AliTradeStatus.TRADE_CLOSED:
						values = "TRADE_CLOSED";
						break;
					case AliTradeStatus.TRADE_FINISHED:
						values = "TRADE_FINISHED";
						tradeNo = response.getTradeNo();
						PlatformBusinessRec businessRecs = platformBusinessRecService.getPlatformBusinessRecByOutTradeNo(prepayParams.getOutTradeNo());
						if (businessRecs != null && org.apache.commons.lang.StringUtils.isBlank(businessRecs.getTradeNo())) {
							businessRecs.setTradeStatus(AliTradeStatus.TRADE_SUCCESS);
							businessRecs.setTradeNo(tradeNo);
							businessRecs.setTradeDate(new Date());
							platformBusinessRecService.updateById(businessRecs);
						}
						break;
					default:
						values = "QUERY_FAILURE";
				}
			} else {
				System.out.println(response.getTradeStatus());
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			values = "QUERY_FAILURE";
		}
		return Json.succ(true, oper, values, tradeNo).data(businessRec);
	}

	@GetMapping("/webPay2")
	public Json webPay2(String orgId, String channelId, String outTradeNo, String subject, String body, String totalAmount) {
		String oper = "alipay_h5pay";
		log.info("{}, body: {}", oper);
		Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
		queryParams.eq("out_trade_no", outTradeNo);
		queryParams.eq("deleted", 0);
		PlatformBusinessRec oldBusinessRec = platformBusinessRecService.selectOne(queryParams);
		if (oldBusinessRec != null) {
			return Json.fail(oper, "该订单号已存在！");
		}
		log.info(getAliPayClient.getAliPayPropertiesMap2().get(AlipayConfig.APPID).getAlipayPublicKey());
		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(orgId);
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,
			AlipayConfig.APPID,
			AlipayConfig.RSA_PRIVATE_KEY,
			AlipayConfig.FORMAT,
			AlipayConfig.CHARSET,
			AlipayConfig.ALIPAY_PUBLIC_KEY,
			AlipayConfig.SIGNTYPE);

		if (sysPaymentMode == null || alipayClient == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
		AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
		model.setProductCode("QUICK_WAP_WAY");
		model.setTimeoutExpress("10m");
		model.setTotalAmount(totalAmount);
		model.setBody(body);
		model.setSubject(subject);
		model.setOutTradeNo(outTradeNo);
		model.setPassbackParams(orgId);
		request.setBizModel(model);
		request.setNotifyUrl("http://njymsb.wicp.vip/server/alipay_api/prepay_notify");
		//		request.getReturnUrl();
		//交易成功回调地址
		String sign;
		try {
			AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
			if (response.isSuccess()) {
				System.out.println("调用成功");
				PlatformBusinessRec businessRec = new PlatformBusinessRec();
				businessRec.setOrgId(orgId);
				businessRec.setChannelId(channelId);
				businessRec.setModeId(sysPaymentMode.getId());
				businessRec.setRecType(Byte.valueOf("1"));
				businessRec.setOutTradeNo(outTradeNo);
				BigDecimal bd = new BigDecimal(totalAmount);
				//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
				bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
				businessRec.setTotalFee(bd);
				businessRec.setAccountFlag(Byte.valueOf("0"));
				businessRec.setAbnormalFlag(Byte.valueOf("0"));
				businessRec.setCreateDate(new Date());
				boolean boo = platformBusinessRecService.insert(businessRec);
				if (!boo) {
					return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
				}
				sign = response.getBody();

			} else {
				return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			return Json.fail(oper).data(e.getMessage());
		}

		return Json.succ(oper).data("调用成功").data("sign", sign);
	}

	/**
	 * 手机浏览器端支付宝支付
	 *
	 * @param appProperties
	 * @return
	 */
	@ApiOperation(value = "H5支付", notes = "手机浏览器端支付宝支付", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "渠道ID", name = "channelId", required = true, dataType = "String", example = "1034683401866588162"),
		@ApiImplicitParam(value = "系统订单号", name = "outTradeNo", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "标题", name = "subject", required = true, dataType = "String", example = "测试标题"),
		@ApiImplicitParam(value = "对一笔交易的具体描述信息", name = "body", required = true, dataType = "String", example = "iphone6 16G"),
		@ApiImplicitParam(value = "描述", name = "describe", required = false, dataType = "String", example = "测试描述"),
		@ApiImplicitParam(value = "订单总金额", name = "totalAmount", required = true, dataType = "BigDecimal", example = "1.00"),
		@ApiImplicitParam(value = "操作员姓名", name = "operatorName", required = true, dataType = "String", example = "操作员1")
	})
	@PostMapping("/webPay")
	public Json webPay(@Valid H5PayParams appProperties, BindingResult bindingResult) {
		String oper = "alipay_h5pay";
		log.info("{}, body: {}", oper, appProperties);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(appProperties.getOrgId());
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(appProperties.getOrgId());
		if (sysPaymentMode == null || alipayClient == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
		AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
		model.setProductCode("QUICK_WAP_WAY");
		model.setTimeoutExpress("10m");
		model.setTotalAmount(appProperties.getTotalAmount());
		model.setBody(appProperties.getBody());
		model.setSubject(appProperties.getSubject());
		model.setOutTradeNo(appProperties.getOutTradeNo());
		model.setPassbackParams(appProperties.getOrgId());
		request.setBizModel(model);
		//交易成功回调地址
		String sign;
		try {
			AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
			if (response.isSuccess()) {
				System.out.println("调用成功");
				PlatformBusinessRec businessRec = new PlatformBusinessRec();
				businessRec.setOrgId(appProperties.getOrgId());
				businessRec.setChannelId(appProperties.getChannelId());
				businessRec.setModeId(sysPaymentMode.getId());
				businessRec.setRecType(Byte.valueOf("1"));
				businessRec.setOutTradeNo(appProperties.getOutTradeNo());
				BigDecimal bd = new BigDecimal(appProperties.getTotalAmount());
				//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
				bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
				businessRec.setTotalFee(bd);
				businessRec.setAccountFlag(Byte.valueOf("0"));
				businessRec.setAbnormalFlag(Byte.valueOf("0"));
				businessRec.setCreateDate(new Date());
				if (appProperties.getOperatorName() != null) {
					businessRec.setOperatorName(appProperties.getOperatorName());
				}
				boolean boo = platformBusinessRecService.insert(businessRec);
				if (!boo) {
					return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
				}
				sign = response.getBody();

			} else {
				return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			return Json.fail(oper).data(e.getMessage());
		}

		return Json.succ(oper).data("调用成功").data("sign", sign);
	}

	/**
	 * 手机app支付宝支付
	 * 支付成功后可回调app支付成功页面
	 *
	 * @return 成功1 失败 -1
	 */
	@ApiOperation(value = "app支付", notes = "app内唤起支付宝支付", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "渠道ID", name = "channelId", required = true, dataType = "String", example = "1034683401866588162"),
		@ApiImplicitParam(value = "系统订单号", name = "outTradeNo", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "标题", name = "subject", required = true, dataType = "String", example = "测试标题"),
		@ApiImplicitParam(value = "对一笔交易的具体描述信息", name = "body", required = true, dataType = "String", example = "iphone6 16G"),
		@ApiImplicitParam(value = "描述", name = "describe", required = false, dataType = "String", example = "测试描述"),
		@ApiImplicitParam(value = "订单总金额", name = "totalAmount", required = true, dataType = "BigDecimal", example = "1.00"),
		@ApiImplicitParam(value = "操作员姓名", name = "operatorName", required = true, dataType = "String", example = "操作员1")
	})
	@PostMapping("/appPay")
	public Json appPay(@Valid AppPayParams appProperties, BindingResult bindingResult) {
		String oper = "alipay_prepay";
		log.info("{}, body: {}", oper, appProperties);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String orgId = appProperties.getOrgId();
		String channelId = appProperties.getChannelId();
		String outTradeNo = appProperties.getOutTradeNo();

		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(orgId);
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(orgId);
		if (sysPaymentMode == null || alipayClient == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setTimeoutExpress("10m");
		model.setTotalAmount(appProperties.getTotalAmount());
		model.setBody(appProperties.getBody());
		model.setStoreId(appProperties.getOrgId());
		model.setSubject(appProperties.getSubject());
		model.setOutTradeNo(appProperties.getOutTradeNo());
		model.setPassbackParams(orgId);
		request.setBizModel(model);
		//交易成功回调地址
		String sign;
		try {
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			if (response.isSuccess()) {
				PlatformBusinessRec businessRec = new PlatformBusinessRec();
				businessRec.setOrgId(orgId);
				businessRec.setChannelId(channelId);
				businessRec.setModeId(sysPaymentMode.getId());
				businessRec.setRecType(Byte.valueOf("1"));
				businessRec.setOutTradeNo(outTradeNo);
				BigDecimal bd = new BigDecimal(appProperties.getTotalAmount());
				//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
				bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
				businessRec.setTotalFee(bd);
				businessRec.setAccountFlag(Byte.valueOf("0"));
				businessRec.setAbnormalFlag(Byte.valueOf("0"));
				businessRec.setCreateDate(new Date());
				if (appProperties.getOperatorName() != null) {
					businessRec.setOperatorName(appProperties.getOperatorName());
				}
				boolean boo = platformBusinessRecService.insert(businessRec);
				if (!boo) {
					return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
				}
				sign = response.getBody();
			} else {
				return Json.fail(oper).data("调用失败，原因：" + response.getSubMsg());
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			return Json.fail(oper).data(e.getMessage());
		}
		return Json.succ(oper).data("调用成功").data("sign", sign);
	}

	@ApiOperation(value = "APP支付回调", notes = "调用APP支付接口支付成功后回调")
	@PostMapping("/appTradeReturn")
	public String appTradeReturn(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String message = "";
		Map<String, String> params = new HashMap<>(16);
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String parameterName = parameterNames.nextElement();
			params.put(parameterName, request.getParameter(parameterName));
		}
		//验证签名
		boolean signVerified = false;
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesMap2().get(params.get("app_id"));

		try {
			signVerified = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAlipayPublicKey(), "UTF-8", aliPayProperties.getSignType());
		}
		catch (AlipayApiException e) {
		}

		if (signVerified) {
			// 若参数中的appid和填入的appid不相同，则为异常通知
			if (!aliPayProperties.getAppid().equals(params.get("app_id"))) {
				log.info("与付款时的appid不同，此为异常通知，应忽略！");
				message = "failed";
			} else {
				String outTradeNo = params.get("out_trade_no");
				log.info(outTradeNo + "号订单回调通知。");
				//在数据库中查找订单号对应的订单，并将其金额与数据库中的金额对比，若对不上，也为异常通知
				Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
				queryParams.eq("out_trade_no", outTradeNo);
				queryParams.eq("deleted", 0);
				PlatformBusinessRec businessRec = platformBusinessRecService.selectOne(queryParams);
				if (businessRec != null) {
					BigDecimal totalFee = businessRec.getTotalFee();
					String totalFeeResult = params.get("total_amount");
					if (new BigDecimal(totalFeeResult).compareTo(totalFee) == 0) {
						String status = params.get("trade_status");
						if (AliTradeStatus.WAIT_BUYER_PAY.equals(status)) {
							// 如果状态是正在等待用户付款
						} else if (AliTradeStatus.TRADE_CLOSED.equals(status)) {
							// 如果状态是未付款交易超时关闭，或支付完成后全额退款
						} else if (AliTradeStatus.TRADE_SUCCESS.equals(status) || AliTradeStatus.TRADE_FINISHED.equals(status)) {
							// 如果状态是已经支付成功
							//成功 更新状态
							String tradeNo = params.get("trade_no");
							businessRec.setTradeNo(tradeNo);
							businessRec.setTradeDate(new Date());
							businessRec.setTradeStatus(status);
							platformBusinessRecService.updateById(businessRec);
							//@TODO APP服务器状态,返回支付结果与tradeNo
							String url = "http://192.168.2.172:8";
						} else {
							message = "failed";
							log.info("订单状态未知！");
						}
					} else {
						message = "failed";
						log.info("金额不符！");
					}
				} else {
					message = "failed";
					log.info("此单不存在！");
				}
			}
		} else {
			// 如果验证签名没有通过
			message = "failed";
			log.info("验证签名失败！");
		}
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(message.getBytes());
		out.flush();
		out.close();
		return message;
	}

	/**
	 * method: 当面付-条码付
	 * 商家使用扫码工具(扫码枪等)扫描用户支付宝的付款码
	 *
	 * @Description:
	 * @pram: a
	 * @reurn: a
	 * @author: yh
	 * @date: 2018/8/28 17:04
	 */
	@ApiOperation(value = "条码付接口", notes = "条码付接口", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "渠道ID", name = "channelId", required = true, dataType = "String", example = "1034683401866588162"),
		@ApiImplicitParam(value = "系统订单号", name = "outTradeNo", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "支付场景: 条码支付，取值：bar_code ;声波支付，取值：wave_code", name = "scene", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "支付授权码，25~30开头的长度为16~24位的数字，实际字符串长度以开发者获取的付款码长度为准", name = "authCode", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "有效时间,取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m", name = "expireTime", required = false, dataType = "String", example = "15m"),
		@ApiImplicitParam(value = "病人卡号", name = "cardNo", dataType = "String", example = "12345678", allowEmptyValue = true),
		@ApiImplicitParam(value = "病人姓名", name = "name", dataType = "String", example = "测试人1", allowEmptyValue = true),
		@ApiImplicitParam(value = "标题", name = "subject", required = true, dataType = "String", example = "测试标题"),
		@ApiImplicitParam(value = "描述", name = "describe", required = true, dataType = "String", example = "测试描述"),
		@ApiImplicitParam(value = "订单总金额", name = "totalAmount", required = true, dataType = "BigDecimal", example = "1.00"), @ApiImplicitParam(value = "商户机具终端编号", name = "terminalId"),
		@ApiImplicitParam(value = "卖家支付宝账号ID", name = "sellerId"), @ApiImplicitParam(value = "商户操作员编号", name = "operatorId", required = true, example = "111111111"),
		@ApiImplicitParam(value = "操作员姓名", name = "operatorName", required = true, dataType = "String", example = "操作员1"),
		@ApiImplicitParam(value = "商品列表", name = "goodsDetailList", paramType = "String"), @ApiImplicitParam(value = "业务扩展参数", name = "extendParamsList", paramType = "String"),
	})
	@PostMapping("/barcodepay")
	public Json barCodePay(@Valid BarCodePayParams barCodePayParams, BindingResult bindingResult) {
		String oper = "alipay_barcodepay";
		log.info("{}, body: {}", oper, barCodePayParams);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String orgId = barCodePayParams.getOrgId();
		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(orgId);
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		if (sysPaymentMode == null || aliPayProperties == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(barCodePayParams.getOrgId());
		AlipayTradePayModel alipayTradePayModel = new AlipayTradePayModel();
		alipayTradePayModel.setOutTradeNo(barCodePayParams.getOutTradeNo());
		alipayTradePayModel.setScene(barCodePayParams.getScene());
		alipayTradePayModel.setAuthCode(barCodePayParams.getAuthCode());
		alipayTradePayModel.setSubject(barCodePayParams.getSubject());
		alipayTradePayModel.setTotalAmount(barCodePayParams.getTotalAmount());
		alipayTradePayModel.setSellerId(barCodePayParams.getSellerId());
		alipayTradePayModel.setBody(barCodePayParams.getDescribe());
		alipayTradePayModel.setOperatorId(barCodePayParams.getOperatorId());
		alipayTradePayModel.setStoreId(barCodePayParams.getOrgId());
		alipayTradePayModel.setTerminalId(barCodePayParams.getTerminalId());
		if(StringUtils.isNotBlank(barCodePayParams.getExpireTime())){
			alipayTradePayModel.setTimeoutExpress(barCodePayParams.getExpireTime());
		}else{
			alipayTradePayModel.setTimeoutExpress("15m");
		}
		alipayTradePayModel.setGoodsDetail(barCodePayParams.getGoodsDetailList());
		AlipayTradePayRequest alipayTradePayRequest = new AlipayTradePayRequest();
		alipayTradePayRequest.setBizModel(alipayTradePayModel);

		String tradeNo;
		AliPayProperties aliPayPropertie = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		try {
			AlipayTradePayResponse response = alipayClient.execute(alipayTradePayRequest, "", aliPayPropertie.getAppAuthToken());
			String code = response.getCode();
			if (AliTradeStatus.QUERY_SUCCESS.equals(code)) {
				if (StringUtils.isNotBlank(response.getTradeNo())) {
					tradeNo = response.getTradeNo();
					// 将支付记录保存到数据库
					this.saveContent(barCodePayParams, sysPaymentMode.getId(), response, response.getTradeNo());
				} else {
					return Json.fail(oper).data(response.getCode() + ":" + response.getSubMsg());
				}
			} else if (AliTradeStatus.WAITING_PAY.equals(code)) {
				// 轮询
				JSONObject jsonObject = this.loopQueryOrder(barCodePayParams.getOutTradeNo(), alipayClient, aliPayProperties);
				String tradeNo1 = jsonObject.getString("tradeNo");
				if (StringUtils.isNotBlank(tradeNo1)) {
					tradeNo = tradeNo1;
					// 将支付记录保存到数据库
					this.saveContent(barCodePayParams, sysPaymentMode.getId(), response, tradeNo1);
				} else {
					return Json.fail(oper, "支付失败，请重新生成订单发起支付");
				}
			} else {
				return Json.fail(oper).data("支付失败：" + response.getCode() + "-" + response.getSubMsg());
			}
		}

		catch (Exception e) {
			return Json.fail(oper).data(e.getMessage());
		}
		return Json.succ(oper).data("支付成功").data("trade_no", tradeNo);
	}

	private void saveContent(BarCodePayParams barCodePayParams, String modeId, AlipayTradePayResponse response, String tradeNo) {
		PlatformBusinessRec businessRec = new PlatformBusinessRec();
		businessRec.setOrgId(barCodePayParams.getOrgId());
		businessRec.setChannelId(barCodePayParams.getChannelId());
		businessRec.setModeId(modeId);
		businessRec.setRecType(Byte.valueOf("1"));
		businessRec.setTradeNo(tradeNo);
		businessRec.setOutTradeNo(barCodePayParams.getOutTradeNo());
		businessRec.setTerminalId(barCodePayParams.getTerminalId());
		businessRec.setTradeStatus(AliTradeStatus.TRADE_SUCCESS);
		businessRec.setCardNo(barCodePayParams.getCardNo());
		businessRec.setName(barCodePayParams.getName());
		BigDecimal bd = new BigDecimal(barCodePayParams.getTotalAmount());
		//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
		bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
		businessRec.setTotalFee(bd);
		businessRec.setTradeDate(new Date());
		businessRec.setAccountFlag(Byte.valueOf("0"));
		businessRec.setAbnormalFlag(Byte.valueOf("0"));
		businessRec.setCreateDate(new Date());
		businessRec.setOperatorId(barCodePayParams.getOperatorId());
		businessRec.setOperatorName(barCodePayParams.getOperatorName());
		platformBusinessRecService.insert(businessRec);
	}

	private JSONObject loopQueryOrder(String outTradeNo, AlipayClient alipayClient, AliPayProperties aliPayProperties) throws AlipayApiException {
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		request.setBizContent("{" + "\"out_trade_no\":\"" + outTradeNo + "\"" + "  }");
		int interval = 5000;
		int queryCount = 10;
		boolean booleanClose = false;
		boolean payResult = false;
		String tradeNo = "";
		do {
			try {
				Thread.sleep(interval);
				queryCount--;
				AlipayTradeQueryResponse response = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
				log.info("values:" + tradeNo + ",payResult:" + payResult + ",booleanClose:" + booleanClose + ",queryCount" + queryCount);
				if (AliTradeStatus.QUERY_SUCCESS.equals(response.getCode())) {
					switch (response.getTradeStatus()) {
						case AliTradeStatus.WAIT_BUYER_PAY:
							break;
						case AliTradeStatus.TRADE_SUCCESS:
							payResult = true;
							tradeNo = response.getTradeNo();
							break;
						case AliTradeStatus.TRADE_CLOSED:
							booleanClose = true;
							break;
						case AliTradeStatus.TRADE_FINISHED:
							payResult = true;
							tradeNo = response.getTradeNo();
							break;
						default:
					}
				} else {
					System.out.println(response.getTradeStatus());
				}
			}
			catch (InterruptedException | AlipayApiException e) {
				e.printStackTrace();
			}

		} while (queryCount > 0 && !payResult && !booleanClose);
		if (tradeNo.isEmpty()) {
			// 退款
			this.cancleTrade(outTradeNo, alipayClient, aliPayProperties);
		}
		JSONObject resultJson = new JSONObject();
		resultJson.put("payResult", payResult);
		resultJson.put("tradeNo", tradeNo);
		return resultJson;

	}

	/**
	 * method: aliPayPrepay
	 *
	 * @Description: 支付宝扫码付接口
	 * @author: yh
	 * @date: 2018/8/27 14:05
	 */
	@ApiOperation(value = "扫码付接口", notes = "调用扫码付接口获取二维码返回给调用者", httpMethod = "POST")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "渠道ID", name = "channelId", required = true, dataType = "String", example = "1034683401866588162"),
		@ApiImplicitParam(value = "有效时间,取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m", name = "expireTime", required = false, dataType = "String", example = "15m"),
		@ApiImplicitParam(value = "系统订单号", name = "outTradeNo", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "病人卡号", name = "cardNo", required = false, dataType = "String", example = "12345678", allowEmptyValue = true),
		@ApiImplicitParam(value = "病人姓名", name = "name", required = false, dataType = "String", example = "测试人1", allowEmptyValue = true),
		@ApiImplicitParam(value = "标题", name = "subject", required = true, dataType = "String", example = "测试标题"),
		@ApiImplicitParam(value = "描述", name = "describe", required = true, dataType = "String", example = "测试描述"),
		@ApiImplicitParam(value = "订单总金额", name = "totalAmount", required = true, dataType = "BigDecimal", example = "1.00"),
		@ApiImplicitParam(value = "卖家支付宝账号ID", name = "sellerId", required = false, example = ""), @ApiImplicitParam(value = "商户操作员编号", name = "operatorId", required = true, example = "111111111"),
		@ApiImplicitParam(value = "操作员姓名", name = "operatorName", required = true, dataType = "String", example = "操作员1"),
		@ApiImplicitParam(value = "商品列表", name = "goodsDetailList", required = false, paramType = "String"),
	})
	@PostMapping("/prepay")
	public Json aliPayPrepay(@Valid PrepayParams prepayParams, BindingResult bindingResult) {
		String oper = "alipay_prepay";
		log.info("{}, body: {}", oper, prepayParams);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String orgId = prepayParams.getOrgId();
		String channelId = prepayParams.getChannelId();
		String outTradeNo = prepayParams.getOutTradeNo();

		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(orgId);
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		if (sysPaymentMode == null || aliPayProperties == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeService alipayTradeService = getAliPayClient.getServiceByAppId(aliPayProperties.getAppid());

		String cardNo = prepayParams.getCardNo();
		String name = prepayParams.getName();
		String subject = prepayParams.getSubject();
		String describe = prepayParams.getDescribe();
		String totalAmount = prepayParams.getTotalAmount();
		String sellerId = prepayParams.getSellerId();
		String storeId = orgId;
		String operatorId = prepayParams.getOperatorId();
		String operatorName = prepayParams.getOperatorName();
		List<GoodsDetail> goodsDetailList = null;
		if (prepayParams.getGoodsDetailList() != null && prepayParams.getGoodsDetailList().size() > 0) {
			goodsDetailList = prepayParams.getGoodsDetailList();
		}

		// 支付超时，线下扫码交易定义为15分钟
		String timeoutExpress = "15m";
		if (StringUtils.isNotBlank(prepayParams.getExpireTime())) {
			timeoutExpress = prepayParams.getExpireTime();
		}

		ExtendParams extendParams = new ExtendParams();
		extendParams.setSysServiceProviderId(aliPayProperties.getPid());
		AlipayTradePrecreateRequestBuilder builder =
			new AlipayTradePrecreateRequestBuilder().setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo).setSellerId(sellerId).setBody(describe).setOperatorId(operatorId)
				.setStoreId(storeId).setTimeoutExpress(timeoutExpress)
				//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
				.setNotifyUrl(aliPayProperties.getNotifyUrl()).setGoodsDetailList(goodsDetailList).setAppAuthToken(aliPayProperties.getAppAuthToken()).setExtendParams(extendParams);

		String qrCode;
		try {
			AlipayF2FPrecreateResult result = alipayTradeService.tradePrecreate(builder);
			if (result.getResponse().getCode().equals(AliTradeStatus.QUERY_SUCCESS)) {
				switch (result.getTradeStatus()) {
					case SUCCESS:
						AlipayTradePrecreateResponse res = result.getResponse();
						qrCode = res.getQrCode();
						// 将支付记录保存到数据库
						PlatformBusinessRec businessRec = new PlatformBusinessRec();
						businessRec.setOrgId(orgId);
						businessRec.setChannelId(channelId);
						businessRec.setModeId(sysPaymentMode.getId());
						businessRec.setRecType(Byte.valueOf("1"));
						businessRec.setOutTradeNo(outTradeNo);
						businessRec.setCardNo(cardNo);
						businessRec.setName(name);
						BigDecimal bd = new BigDecimal(totalAmount);
						//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
						bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
						businessRec.setTotalFee(bd);
						businessRec.setTradeDate(new Date());
						businessRec.setAccountFlag(Byte.valueOf("0"));
						businessRec.setAbnormalFlag(Byte.valueOf("0"));
						businessRec.setCreateDate(new Date());
						businessRec.setOperatorId(operatorId);
						businessRec.setOperatorName(operatorName);
						platformBusinessRecService.insert(businessRec);
						break;
					case FAILED:
						return Json.fail(oper).data(result.getResponse().getSubMsg());
					case UNKNOWN:
						return Json.fail(oper).data(result.getResponse().getSubMsg());
					default:
						return Json.fail(oper).data(result.getResponse().getSubMsg());
				}
			} else {
				return Json.fail(oper).data(result.getResponse().getSubMsg());
			}
		}
		catch (Exception e) {
			return Json.fail(oper).data(e.getMessage());
		}
		return Json.succ(oper).data("qr_code", qrCode).data("timeout_express", timeoutExpress);
	}

	@ApiOperation(value = "扫码付回调", notes = "调用扫码付接口支付成功后回调")
	@PostMapping("/prepay_notify")
	public String prepayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String message = "success";
		Map<String, String> params = new HashMap<>(16);
		// 取出所有参数是为了验证签名
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String parameterName = parameterNames.nextElement();
			params.put(parameterName, request.getParameter(parameterName));
		}

		//验证签名
		boolean signVerified = false;
		log.info("appid:" + params.get("app_id"));
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesMap2().get(params.get("app_id"));

		try {
			signVerified = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAlipayPublicKey(), "UTF-8", aliPayProperties.getSignType());
		}
		catch (AlipayApiException e) {
		}
		if (signVerified) {
			// 若参数中的appid和填入的appid不相同，则为异常通知
			if (!aliPayProperties.getAppid().equals(params.get("app_id")) && !aliPayProperties.getAppId().equals(params.get("app_id"))) {
				log.info("与付款时的appid不同，此为异常通知，应忽略！");
				message = "failed";
			} else {
				String outTradeNo = params.get("out_trade_no");
				log.info(outTradeNo + "号订单回调通知。");
				//在数据库中查找订单号对应的订单，并将其金额与数据库中的金额对比，若对不上，也为异常通知
				Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
				queryParams.eq("out_trade_no", outTradeNo);
				queryParams.eq("deleted", 0);
				PlatformBusinessRec businessRec = platformBusinessRecService.selectOne(queryParams);
				Wrapper<SysOrganization> queryParamse = new EntityWrapper<>();
				queryParamse.eq("id",businessRec.getOrgId());
				SysOrganization sysOrganization = sysOrganizationService.selectOne(queryParamse);

				if (businessRec != null) {
					BigDecimal totalFee = businessRec.getTotalFee();
					String totalFeeResult = params.get("total_amount");
					if (new BigDecimal(totalFeeResult).compareTo(totalFee) == 0) {
						String status = params.get("trade_status");
						if (AliTradeStatus.WAIT_BUYER_PAY.equals(status)) {
							// 如果状态是正在等待用户付款
						} else if (AliTradeStatus.TRADE_CLOSED.equals(status)) {
							// 如果状态是未付款交易超时关闭，或支付完成后全额退款
						} else if (AliTradeStatus.TRADE_SUCCESS.equals(status) || AliTradeStatus.TRADE_FINISHED.equals(status)) {
							// 如果状态是已经支付成功
							//成功 更新状态
							String tradeNo = params.get("trade_no");
							businessRec.setTradeNo(tradeNo);
							businessRec.setTradeDate(new Date());
							businessRec.setTradeStatus(status);
							platformBusinessRecService.updateById(businessRec);
							//@TODO 更新HIS库状态,返回支付结果与tradeNo
							log.info("更新HIS库状态,返回支付结果与tradeNo");
							SimpleDateFormat dateformat=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss ");
							String date=dateformat.format(businessRec.getTradeDate());
							webService.sendPost(sysOrganization.getNotifyUrl(),"outTradeNo="+businessRec.getOutTradeNo()+"&tradeNo="+tradeNo+"&totalFee="+businessRec.getTotalFee()+"&tradeType=alipay&tradeDate="+date);
						} else {
							message = "failed";
							log.info("订单状态未知！");
						}
					} else {
						message = "failed";
						log.info("金额不符！");
					}
				} else {
					message = "failed";
					log.info("此单不存在！");
				}
			}
		} else {
			// 如果验证签名没有通过
			message = "failed";
			log.info("验证签名失败！");
		}
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(message.getBytes());
		out.flush();
		out.close();
		return message;
	}

	/**
	 * method: refund
	 *
	 * @Description: 支付宝退款
	 * @param: [orderNo] 商户订单号
	 * @return: java.lang.String
	 * @author: yh
	 * @date: 2018/8/29 15:20
	 */
	@ApiOperation(value = "支付宝退款接口", notes = "支付宝退款接口")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "渠道ID", name = "channelId", required = true, dataType = "String", example = "1034683401866588162"),
		@ApiImplicitParam(value = "原系统订单号", name = "outTradeNo", required = true, dataType = "String", example = "1111111141111"),
		@ApiImplicitParam(value = "系统退款单号", name = "outRefundNo", required = true, dataType = "String", example = "1111111141122"),
		@ApiImplicitParam(value = "退款金额,该金额不能大于订单金额,单位为元，支持两位小数", name = "refundAmount", required = true, dataType = "String", example = "1.00"),
		@ApiImplicitParam(value = "退款理由", name = "refundReason", required = true, dataType = "String", example = "正常退款"),
		@ApiImplicitParam(value = "商户操作员编号", name = "operatorId", required = true, example = "111111111"),
		@ApiImplicitParam(value = "操作员姓名", name = "operatorName", required = true, dataType = "String", example = "操作员1"),
	})
	@PostMapping("/refund")
	public Json refund(@Valid RefundParams refundParams, BindingResult bindingResult) {
		String oper = "alipay_refund";
		log.info("{}, body: {}", oper, refundParams);
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
		queryParams.eq("out_trade_no", refundParams.getOutTradeNo());
		queryParams.eq("org_id", refundParams.getOrgId());
		queryParams.eq("deleted", 0);
		PlatformBusinessRec businessRec = platformBusinessRecService.selectOne(queryParams);
		if (businessRec == null) {
			return Json.fail(oper).data("订单不存在");
		}
		Wrapper<PlatformBusinessRec> queryRefundParams = new EntityWrapper<>();
		queryRefundParams.eq("out_request_no", refundParams.getOutRefundNo());
		queryRefundParams.eq("org_id", refundParams.getOrgId());
		queryRefundParams.eq("deleted", 0);
		PlatformBusinessRec oldRefundBusinessRec = platformBusinessRecService.selectOne(queryRefundParams);
		if (oldRefundBusinessRec != null) {
			return Json.fail(oper).data("退款记录已存在");
		}
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(refundParams.getOrgId());
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(refundParams.getOrgId());
		if (alipayClient == null || aliPayProperties == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeRefundApplyModel alipayTradeRefundApplyModel = new AlipayTradeRefundApplyModel();
		alipayTradeRefundApplyModel.setOutTradeNo(refundParams.getOutTradeNo());
		alipayTradeRefundApplyModel.setRefundAmount(refundParams.getRefundAmount());
		alipayTradeRefundApplyModel.setStoreId(refundParams.getOrgId());
		alipayTradeRefundApplyModel.setOutRequestNo(refundParams.getOutRefundNo());
		alipayTradeRefundApplyModel.setRefundReason(refundParams.getRefundReason());
		AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
		alipayTradeRefundRequest.setBizModel(alipayTradeRefundApplyModel);
		try {
			AlipayTradeRefundResponse response = alipayClient.execute(alipayTradeRefundRequest,"",aliPayProperties.getAppAuthToken());
		    if(response.isSuccess()){
			    // 将支付记录保存到数据库
			    PlatformBusinessRec businessRecRefund = new PlatformBusinessRec();
			    businessRecRefund.setOrgId(refundParams.getOrgId());
			    businessRecRefund.setChannelId(refundParams.getChannelId());
			    businessRecRefund.setModeId(businessRec.getModeId());
			    businessRecRefund.setRecType(Byte.valueOf("2"));
			    businessRecRefund.setTradeNo(businessRec.getTradeNo());
			    businessRecRefund.setOutTradeNo(businessRec.getOutTradeNo());
			    businessRecRefund.setOutRequestNo(refundParams.getOutRefundNo());
			    businessRecRefund.setTerminalId(businessRec.getTerminalId());
			    businessRecRefund.setCardNo(businessRec.getCardNo());
			    businessRecRefund.setName(businessRec.getName());
			    BigDecimal bd = new BigDecimal(refundParams.getRefundAmount());
			    bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
			    businessRecRefund.setTotalFee(bd);
			    businessRecRefund.setTradeDate(new Date());
			    businessRecRefund.setTradeStatus(AliTradeStatus.TRADE_SUCCESS);
			    businessRecRefund.setAccountFlag(Byte.valueOf("0"));
			    businessRecRefund.setAbnormalFlag(Byte.valueOf("0"));
			    businessRecRefund.setCreateDate(new Date());
			    businessRecRefund.setOperatorId(refundParams.getOperatorId());
			    businessRecRefund.setOperatorName(refundParams.getOperatorName());
			    platformBusinessRecService.insert(businessRecRefund);
		    }else {
			    return Json.fail(oper, response.getSubMsg());
		    }
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			return Json.fail(oper, "不支持的交易状态，交易返回异常!!!");
		}
		return Json.succ(oper, "支付宝退款成功");
	}

	/**
	 * 支付宝撤销交易接口
	 *
	 * @param prepayParams 退款参数
	 * @return 1：成功 -1:失败
	 */
	@ApiOperation(value = "支付宝撤销交易接口", notes = "撤销接口")
	@ApiImplicitParams({
		@ApiImplicitParam(value = "机构ID", name = "orgId", required = true, dataType = "String", example = "1032882050992017410"),
		@ApiImplicitParam(value = "商户生成的交易号", name = "outTradeNo", required = true, dataType = "String", example = "20190222130826711"),
	})
	@PostMapping("/reverseOrder")
	public Json reverseOrder(@Valid reverseOrderParams prepayParams, BindingResult bindingResult) {
		String oper = "alipay_reverse";
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		String orgId = prepayParams.getOrgId();

		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		if (aliPayProperties == null) {
			return Json.fail(oper, "本机构支付宝未配置或配置不正确！");
		}
		AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
		AlipayTradeCancelModel model = new AlipayTradeCancelModel();
		model.setOutTradeNo(prepayParams.getOutTradeNo());
		request.setBizModel(model);
		AlipayClient alipayClient =
			new DefaultAlipayClient(aliPayProperties.getOpenApiDomain(), aliPayProperties.getAppid(), aliPayProperties.getPrivateKey(), "json", "UTF-8", aliPayProperties.getAlipayPublicKey(), "RSA2");
		try {
			AlipayTradeCancelResponse response = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
			if (response.isSuccess()) {
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
				return Json.fail(oper).data(response.getSubMsg());
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			return Json.fail(oper).data(e.getMessage());
		}
		return Json.succ(oper).data("调用成功");
	}

	//取消交易
	private void cancleTrade(String outTradeNo, AlipayClient alipayClient, AliPayProperties aliPayProperties) {
		AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
		AlipayTradeCancelModel model = new AlipayTradeCancelModel();
		model.setOutTradeNo(outTradeNo);
		request.setBizModel(model);
		try {
			AlipayTradeCancelResponse response = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
			if (response.isSuccess()) {
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
			}
		}
		catch (AlipayApiException e) {
			e.printStackTrace();
		}
	}
}

